#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "MSTK.h"


int main(int argc, char *argv[]) {
  int i, k, len, suff, ok;
  char mname[256], filename[256];
  Mesh_ptr mesh;
  /* default divide into two parts */
  int num = 2;
  int ring = 0;
  int verbose = 0;
  /* command line parameter */
  
  if (argc == 1) {
    fprintf(stdout, "pmesh_build_ptype partition the mesh into submeshes and \
                     build PType on each submesh\n");
    fprintf(stdout, "Usage: pmesh_build_ptype -n 4 -r 1 filename\n");
    fprintf(stdout, "Output: submeshes in mstk and pmstk format\n");
    fprintf(stdout, "Option: -h for help\n");
    fprintf(stdout, "        -n number of partition\n");
    fprintf(stdout, "        -r number of ring\n");
    return -1;
  }
  argc--;
  argv++;
    
  while (argc >= 1)
    {
      if (argv[0][0] == '-') {	
	switch(argv[0][1]) {
	case 'h':
	case 'H':
	  fprintf(stdout, "pmesh_build_ptype partition the mesh into submeshes and \
                     build PType on each submesh\n");
	  fprintf(stdout, "Usage: pmesh_build_ptype -n 4 -r 1 filename\n");
	  fprintf(stdout, "Output: submeshes in mstk and pmstk format\n");
	  fprintf(stdout, "Option: -h for help\n");
	  fprintf(stdout, "        -n number of partition\n");
	  fprintf(stdout, "        -r number of ring\n");
   	  argc -= 1;
          argv += 1;
	  return -1;
	  break;
	case 'n':
	case 'N':
	  num = atoi(argv[1]);
	  argc -= 2;
	  argv += 2;
          break;
	case 'v':
	case 'V':
	  verbose = 1;
	  argc -= 1;
	  argv += 1;
	  break;
	case 'r':
	case 'R':
	  ring = atoi(argv[1]);
	  argc -= 2;
	  argv += 2;
	  break;
	}
      }
      else {
	strcpy(mname,argv[0]);
	argc -= 1;
	argv += 1;
      }
    }
 


  /* Initialize MSTK - Always do this even if it does not seem to
     matter in this version of MSTK */

  MSTK_Init();


  /* Build the global attributes list */
  char attname[256];
  MAttrib_ptr attrib;
  List_ptr attrib_list = List_New(2);
  strcpy(attname,"coordinates");
  attrib = MAttrib_New(NULL,attname,VECTOR,MVERTEX,3);
  List_Add(attrib_list,attrib);

  strcpy(attname,"Face_PType");
  attrib = MAttrib_New(NULL,attname,INT,MFACE);
  List_Add(attrib_list,attrib);


  /* Load the mesh */
  mname[len-5] = '\0';

  strcpy(filename,mname);
  strcat(filename,".mstk");

  mesh = MESH_New(UNKNOWN_REP);
  ok = MESH_InitFromFile(mesh,filename);
  if (!ok) {
    fprintf(stderr,"Cannot open input file %s\n\n\n",filename);
    exit(-1);
  }
  fprintf(stdout,"mstk mesh %s read in successfully\n",filename);

  /* Partition the mesh*/
  RepType rtype = MESH_RepType(mesh);
  Mesh_ptr *submeshes = (Mesh_ptr *)MSTK_malloc(num*sizeof(Mesh_ptr));
  ok = MESH_Partition(mesh,submeshes,num);
  fprintf(stdout,"%s has been partitioned into %d submeshes\n",filename,num);

  char buf[256];
  char subfilename[256];

  /* add coordinates as attributes */
  MESH_InitializeAttr(mesh,attrib_list);
  MESH_AttrCoord(mesh,0);
  
  for (i = 0 ; i < num ; i++) {
    /* initialze attributes*/
    MESH_InitializeAttr(submeshes[i],attrib_list);
    strcpy(subfilename,mname);
    itoa(i,buf);
    strcat(subfilename,buf);
    strcat(subfilename,".mstk");
    MESH_WriteToFile(submeshes[i],subfilename,rtype);
    /* built ptype */
    MESH_BuildPType(mesh,submeshes[i]);
    /* add ghost */
    MESH_AddGhost(mesh,submeshes[i],1);
    /* copy coordinates attribute */
    MESH_CopyAttr(mesh,submeshes[i],0);
    /* add ptype into attributes for debugging*/
    MESH_Surf_AttrPType(submeshes[i],1);

    fprintf(stdout,"PType of submesh %d has been built\n",i);
    strcpy(subfilename,mname);
    itoa(i,buf);
    strcat(subfilename,buf);
    strcat(subfilename,"-with-attr.mstk");

    /* write regular mstk mesh */
    MESH_WriteToFile(submeshes[i],subfilename,rtype);
    fprintf(stdout,"submesh %d has been written into %s\n",i,subfilename);
    strcpy(subfilename,mname);
    itoa(i,buf);
    strcat(subfilename,buf);
    strcat(subfilename,"-P-add-ghost.mstk");
    /* write parallel mstk mesh */
    PMESH_WriteToFile(submeshes[i],subfilename,rtype);
    fprintf(stdout,"parallel submesh %d has been written into %s\n",i,subfilename);

  }  

  /* Deleting of mesh is not necessary if this the end of the program */
  for (i = 0; i < num; i++)
    MESH_Delete(submeshes[i]);
  /* Write out a copy of the mesh */
  strcpy(filename,mname);
  strcat(filename,"-copy.mstk");
  MESH_WriteToFile(mesh,filename,rtype);

  return 1;
}

